package com.dms.modules.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dms.common.exception.BusinessException;
import com.dms.common.utils.RedisUtils;
import com.dms.common.utils.SecurityUtils;
import com.dms.modules.product.dto.ProductDTO;
import com.dms.modules.product.dto.ProductParameterDTO;
import com.dms.modules.product.dto.ProductSpecificationDTO;
import com.dms.modules.product.dto.ProductSearchDTO;
import com.dms.modules.product.dto.ProductQueryDTO;
import com.dms.modules.product.dto.ProductAttributeDTO;
import com.dms.modules.product.dto.ProductSkuDTO;
import com.dms.modules.product.dto.ProductSpecDTO;
import com.dms.modules.product.entity.Product;
import com.dms.modules.product.entity.ProductSku;
import com.dms.modules.product.entity.ProductCategory;
import com.dms.modules.product.entity.ProductReview;
import com.dms.modules.product.mapper.ProductMapper;
import com.dms.modules.product.mapper.ProductReviewMapper;
import com.dms.modules.product.service.ProductService;
import com.dms.modules.product.service.ProductSkuService;
import com.dms.modules.product.service.ProductCategoryService;
import com.dms.modules.product.vo.ProductDetailVO;
import com.dms.modules.product.vo.ProductVO;
import com.dms.modules.product.vo.ProductReviewVO;
import com.dms.modules.merchant.entity.Merchant;
import com.dms.modules.product.entity.UserBrowseHistory;
import com.dms.modules.user.entity.UserFavorite;
import com.dms.modules.user.entity.User;
import com.dms.modules.user.service.UserBrowseHistoryService;
import com.dms.modules.user.service.UserFavoriteService;
import com.dms.modules.user.service.UserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.Set;
import java.util.Collections;
import java.util.Map;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Date;
import java.util.stream.Collectors;

/**
 * 商品服务实现类
 */
@Slf4j
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {

    private static final String PRODUCT_CACHE_KEY = "product:detail:";
    private static final String PRODUCT_SEARCH_CACHE_KEY = "product:search:";
    private static final long PRODUCT_CACHE_EXPIRE = 24; // 24小时
    private static final long SEARCH_CACHE_EXPIRE = 5; // 5分钟
    private static final String SEARCH_HISTORY_KEY = "user:search:history:";
    private static final int MAX_SEARCH_HISTORY = 10;
    private static final String SEARCH_SUGGESTIONS_KEY = "product:search:suggestions";
    private static final String HOT_SEARCH_KEY = "product:search:hot";
    private static final int MAX_SUGGESTIONS = 10;

    private final ObjectMapper objectMapper;
    private final RedisUtils redisUtils;
    private final ProductSkuService skuService;
    private final ProductCategoryService categoryService;
    private final UserBrowseHistoryService userBrowseHistoryService;
    private final ProductReviewMapper reviewMapper;
    private final UserService userService;

    @Autowired
    private RedisTemplate<String, ProductDetailVO> productDetailRedisTemplate;

    public ProductServiceImpl(ObjectMapper objectMapper,
                            RedisUtils redisUtils,
                            ProductSkuService skuService,
                            ProductCategoryService categoryService,
                            UserBrowseHistoryService userBrowseHistoryService,
                            ProductReviewMapper reviewMapper,
                            UserService userService) {
        this.objectMapper = objectMapper;
        this.redisUtils = redisUtils;
        this.skuService = skuService;
        this.categoryService = categoryService;
        this.userBrowseHistoryService = userBrowseHistoryService;
        this.reviewMapper = reviewMapper;
        this.userService = userService;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean create(ProductDTO productDTO) {
        try {
            // 1. 验证商品基本信息
            validateProductBasicInfo(productDTO);
            
            // 2. 创建商品基本信息
            Product product = new Product();
            BeanUtils.copyProperties(productDTO, product);
            
            // 3. 处理规格信息
            if (productDTO.getSpecs() != null) {
                validateProductSpecs(productDTO.getSpecs());
                product.setSpecs(objectMapper.writeValueAsString(productDTO.getSpecs()));
            }
            
            // 4. 设置默认值
            product.setStatus(1);
            product.setAuditStatus(0);
            product.setSales(0);
            product.setViewCount(0);
            product.setFavoriteCount(0);
            
            // 5. 保存商品
            save(product);
            
            // 6. 处理SKU
            if (Boolean.TRUE.equals(productDTO.getEnableSpec()) && productDTO.getSkuList() != null) {
                validateSkuList(productDTO.getSkuList());
                for (ProductSkuDTO skuDTO : productDTO.getSkuList()) {
                    skuDTO.setProductId(product.getId());
                    // 自动生成SKU名称
                    String skuName = generateSkuName(product.getName(), skuDTO.getSpecValues());
                    skuDTO.setSkuName(skuName);
                    validateSkuInfo(skuDTO);
                    skuService.create(skuDTO);
                }
            } else {
                // 如果没有启用规格，创建一个默认SKU
                ProductSkuDTO defaultSku = new ProductSkuDTO();
                defaultSku.setProductId(product.getId());
                defaultSku.setSkuName(product.getName());
                defaultSku.setPrice(product.getPrice());
                defaultSku.setStock(product.getStock());
                defaultSku.setStatus(1);
                validateSkuInfo(defaultSku);
                skuService.create(defaultSku);
            }
            
            return true;
        } catch (Exception e) {
            log.error("创建商品失败", e);
            throw new BusinessException("创建商品失败：" + e.getMessage());
        }
    }

    /**
     * 验证商品基本信息
     */
    private void validateProductBasicInfo(ProductDTO productDTO) {
        if (productDTO == null) {
            throw new BusinessException("商品信息不能为空");
        }
        if (!StringUtils.hasText(productDTO.getName())) {
            throw new BusinessException("商品名称不能为空");
        }
        if (productDTO.getPrice() == null || productDTO.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException("商品价格必须大于0");
        }
        if (productDTO.getStock() == null || productDTO.getStock() < 0) {
            throw new BusinessException("商品库存不能小于0");
        }
        if (productDTO.getCategoryId() == null) {
            throw new BusinessException("商品分类不能为空");
        }
        if (productDTO.getMerchantId() == null) {
            throw new BusinessException("商家ID不能为空");
        }
    }

    /**
     * 验证商品规格信息
     */
    private void validateProductSpecs(List<ProductSpecDTO> specs) {
        if (specs == null || specs.isEmpty()) {
            throw new BusinessException("商品规格不能为空");
        }
        for (ProductSpecDTO spec : specs) {
            if (!StringUtils.hasText(spec.getName())) {
                throw new BusinessException("规格名称不能为空");
            }
            if (spec.getValues() == null || spec.getValues().isEmpty()) {
                throw new BusinessException("规格值不能为空");
            }
        }
    }

    /**
     * 验证SKU列表
     */
    private void validateSkuList(List<ProductSkuDTO> skuList) {
        if (skuList == null || skuList.isEmpty()) {
            throw new BusinessException("SKU列表不能为空");
        }
        
        // 验证每个SKU的规格值是否完整
        for (ProductSkuDTO sku : skuList) {
            if (sku.getSpecValues() == null || sku.getSpecValues().isEmpty()) {
                throw new BusinessException("SKU规格值不能为空");
            }
        }
        
        // 检查SKU名称是否重复
        Set<String> skuNames = new HashSet<>();
        for (ProductSkuDTO sku : skuList) {
            String skuName = generateSkuName(sku.getSkuName(), sku.getSpecValues());
            if (skuNames.contains(skuName)) {
                throw new BusinessException("SKU名称不能重复");
            }
            skuNames.add(skuName);
        }
    }

    /**
     * 验证SKU信息
     */
    private void validateSkuInfo(ProductSkuDTO skuDTO) {
        if (skuDTO == null) {
            throw new BusinessException("SKU信息不能为空");
        }
        if (!StringUtils.hasText(skuDTO.getSkuName())) {
            throw new BusinessException("SKU名称不能为空");
        }
        if (skuDTO.getPrice() == null || skuDTO.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException("SKU价格必须大于0");
        }
        if (skuDTO.getStock() == null || skuDTO.getStock() < 0) {
            throw new BusinessException("SKU库存不能小于0");
        }
        if (skuDTO.getProductId() == null) {
            throw new BusinessException("商品ID不能为空");
        }
    }

    /**
     * 生成SKU名称
     */
    private String generateSkuName(String productName, Map<String, String> specValues) {
        if (!StringUtils.hasText(productName)) {
            throw new BusinessException("商品名称不能为空");
        }
        
        if (specValues == null || specValues.isEmpty()) {
            return productName;
        }
        
        StringBuilder skuName = new StringBuilder(productName);
        // 按照规格名称排序，确保生成的SKU名称顺序一致
        specValues.entrySet().stream()
            .sorted(Map.Entry.comparingByKey())
            .forEach(entry -> {
                if (!StringUtils.hasText(entry.getValue())) {
                    throw new BusinessException("规格值不能为空");
                }
                skuName.append(" ").append(entry.getValue());
            });
            
        return skuName.toString().trim();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(ProductDTO productDTO) {
        try {
            // 1. 验证商品是否存在
            Product existingProduct = getById(productDTO.getId());
            if (existingProduct == null) {
                throw new BusinessException("商品不存在");
            }
            
            // 2. 更新商品基本信息
            Product product = new Product();
            BeanUtils.copyProperties(productDTO, product);
            
            // 3. 处理规格信息
            if (productDTO.getSpecs() != null) {
                product.setSpecs(objectMapper.writeValueAsString(productDTO.getSpecs()));
            }
            
            // 4. 更新商品
            updateById(product);
            
            // 5. 处理SKU
            if (Boolean.TRUE.equals(productDTO.getEnableSpec()) && productDTO.getSkuList() != null) {
                // 删除原有SKU
                skuService.deleteByProductId(product.getId());
                
                // 创建新的SKU
                for (ProductSkuDTO skuDTO : productDTO.getSkuList()) {
                    skuDTO.setProductId(product.getId());
                    skuDTO.setSkuName(generateSkuName(product.getName(), skuDTO.getSpecValues()));
                    skuService.create(skuDTO);
                }
            }
            
            return true;
        } catch (Exception e) {
            log.error("更新商品失败", e);
            throw new BusinessException("更新商品失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delete(Long id) {
        try {
            // 1. 删除商品
            removeById(id);
            
            // 2. 删除相关SKU
            skuService.deleteByProductId(id);
            
            return true;
        } catch (Exception e) {
            log.error("删除商品失败", e);
            throw new BusinessException("删除商品失败：" + e.getMessage());
        }
    }

    @Override
    public int countMerchantProducts(Long merchantId) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getMerchantId, merchantId)
               .eq(Product::getStatus, 1);
        return Math.toIntExact(this.count(wrapper));
    }

    @Override
    public boolean addProduct(Product product) {
        ProductDTO productDTO = new ProductDTO();
        BeanUtils.copyProperties(product, productDTO);
        return create(productDTO);
    }

    @Override
    public boolean updateProduct(Product product) {
        ProductDTO productDTO = new ProductDTO();
        BeanUtils.copyProperties(product, productDTO);
        return update(productDTO);
    }

    @Override
    public boolean deleteProduct(Long id) {
        return delete(id);
    }

    @Override
    public ProductDTO getDetail(Long id) {
        Product product = getById(id);
        if (product == null) {
            return null;
        }
        ProductDTO productDTO = new ProductDTO();
        BeanUtils.copyProperties(product, productDTO);
        
        // 处理商品子图
        if (StringUtils.hasText(product.getSubImages())) {
            productDTO.setSubImages(Arrays.asList(product.getSubImages().split(",")));
        }
        return productDTO;
    }

    @Override
    public ProductDetailVO getProductDetail(Long id) {
        try {
            // 1. 获取商品信息
            Product product = getById(id);
            if (product == null) {
                throw new BusinessException("商品不存在");
            }
            
            // 2. 获取SKU信息
            List<ProductSku> skuList = skuService.getByProductId(id);
            
            // 3. 构建详情VO
            ProductDetailVO detailVO = new ProductDetailVO();
            BeanUtils.copyProperties(product, detailVO);
            
            // 4. 处理规格信息
            if (StringUtils.hasText(product.getSpecs())) {
                try {
                    detailVO.setSpecs(objectMapper.readValue(product.getSpecs(), List.class));
                } catch (JsonProcessingException e) {
                    log.error("解析商品规格信息失败", e);
                }
            }
            
            // 5. 处理SKU信息
            detailVO.setSkuList(skuList.stream()
                    .map(sku -> {
                        ProductSkuDTO skuDTO = new ProductSkuDTO();
                        BeanUtils.copyProperties(sku, skuDTO);
                        if (StringUtils.hasText(sku.getSpecValues())) {
                            try {
                                skuDTO.setSpecValues(objectMapper.readValue(sku.getSpecValues(), Map.class));
                            } catch (JsonProcessingException e) {
                                log.error("解析SKU规格值失败", e);
                            }
                        }
                        return skuDTO;
                    })
                    .collect(Collectors.toList()));
            
            return detailVO;
        } catch (Exception e) {
            log.error("获取商品详情失败", e);
            throw new BusinessException("获取商品详情失败：" + e.getMessage());
        }
    }

    @Override
    public Page<Product> list(Page<Product> page, Long categoryId, String keyword, Integer status) {
        log.debug("查询商品列表: categoryId={}, keyword={}, status={}", categoryId, keyword, status);
        
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getDeleted, false)
               .eq(status != null, Product::getStatus, status)
               .eq(categoryId != null, Product::getCategoryId, categoryId)
               .and(keyword != null && !keyword.trim().isEmpty(), w -> w
                   .like(Product::getName, keyword)
                   .or()
                   .like(Product::getSubtitle, keyword)
                   .or()
                   .like(Product::getDetail, keyword))
               .orderByDesc(Product::getCreateTime);
        
        return baseMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(Long id, Integer status) {
        try {
            // 1. 验证商品是否存在
            Product product = getById(id);
            if (product == null) {
                throw new BusinessException("商品不存在");
            }
            
            // 2. 更新状态
            product.setStatus(status);
            return updateById(product);
        } catch (Exception e) {
            log.error("更新商品状态失败", e);
            throw new BusinessException("更新商品状态失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStock(Long id, Integer quantity) {
        Product product = getById(id);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }
        
        if (product.getStock() + quantity < 0) {
            throw new BusinessException("库存不足");
        }
        
        product.setStock(product.getStock() + quantity);
        boolean result = updateById(product);
        if (result) {
            redisUtils.delete(PRODUCT_CACHE_KEY + id);
        }
        return result;
    }

    @Override
    public IPage<Product> search(ProductSearchDTO searchDTO) {
        log.debug("Searching products with criteria: {}", searchDTO);
        
        // 构建查询条件
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(searchDTO.getKeyword())) {
            queryWrapper.like(Product::getName, searchDTO.getKeyword())
                    .or()
                    .like(Product::getDetail, searchDTO.getKeyword());
            // 保存搜索历史
            Long userId = SecurityUtils.getCurrentUserId();
            if (userId != null) {
                saveSearchHistory(userId, searchDTO.getKeyword());
            }
        }
        
        // 分类过滤
        if (!CollectionUtils.isEmpty(searchDTO.getCategoryIds())) {
            queryWrapper.in(Product::getCategoryId, searchDTO.getCategoryIds());
        }
        
        // 价格范围
        if (searchDTO.getMinPrice() != null) {
            queryWrapper.ge(Product::getPrice, searchDTO.getMinPrice());
        }
        if (searchDTO.getMaxPrice() != null) {
            queryWrapper.le(Product::getPrice, searchDTO.getMaxPrice());
        }
        
        // 销量范围
        if (searchDTO.getMinSales() != null) {
            queryWrapper.ge(Product::getSales, searchDTO.getMinSales());
        }
        if (searchDTO.getMaxSales() != null) {
            queryWrapper.le(Product::getSales, searchDTO.getMaxSales());
        }
        
        // 商家过滤
        if (searchDTO.getShopId() != null) {
            queryWrapper.eq(Product::getMerchantId, searchDTO.getShopId());
        }
        
        // 库存过滤
        if (searchDTO.getHasStock() != null && searchDTO.getHasStock() == 1) {
            queryWrapper.gt(Product::getStock, 0);
        }
        
        // 排序
        if (searchDTO.getSortField() != null) {
            switch (searchDTO.getSortField()) {
                case 1: // 综合排序
                    queryWrapper.orderByDesc(Product::getSales)
                            .orderByDesc(Product::getCreateTime);
                    break;
                case 2: // 销量
                    queryWrapper.orderByDesc(Product::getSales);
                    break;
                case 3: // 价格升序
                    queryWrapper.orderByAsc(Product::getPrice);
                    break;
                case 4: // 价格降序
                    queryWrapper.orderByDesc(Product::getPrice);
                    break;
                case 5: // 最新
                    queryWrapper.orderByDesc(Product::getCreateTime);
                    break;
                default:
                    queryWrapper.orderByDesc(Product::getCreateTime);
            }
        } else {
            queryWrapper.orderByDesc(Product::getCreateTime);
        }
        
        // 只查询上架商品
        queryWrapper.eq(Product::getStatus, 1);
        queryWrapper.eq(Product::getDeleted, 0);
        
        // 执行分页查询
        Page<Product> page = new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize());
        return page(page, queryWrapper);
    }

    @Override
    public IPage<Product> getProductList(ProductQueryDTO queryDTO) {
        try {
            // 1. 构建查询条件
            LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(queryDTO.getMerchantId() != null, Product::getMerchantId, queryDTO.getMerchantId())
                    .eq(queryDTO.getCategoryId() != null, Product::getCategoryId, queryDTO.getCategoryId())
                    .eq(queryDTO.getStatus() != null, Product::getStatus, queryDTO.getStatus())
                    .like(StringUtils.hasText(queryDTO.getName()), Product::getName, queryDTO.getName())
                    .orderByDesc(Product::getCreateTime);
            
            // 2. 执行分页查询
            Page<Product> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
            return page(page, wrapper);
        } catch (Exception e) {
            log.error("获取商品列表失败", e);
            throw new BusinessException("获取商品列表失败：" + e.getMessage());
        }
    }

    @Override
    public List<ProductDetailVO> getRecommendProducts() {
        try {
            // 尝试获取当前用户ID，如果获取失败则返回热门商品
            Long userId;
            try {
                userId = SecurityUtils.getCurrentUserId();
            } catch (Exception e) {
                log.info("User not authenticated or ID not available, returning hot products instead");
                return getHotProducts(20);
            }
            
            log.info("Getting recommended products for user: {}", userId);
            
            // Get user's recent browsing history
            List<UserBrowseHistory> browseHistory = userBrowseHistoryService.getUserRecentBrowseHistory(userId, 10);
            List<Long> browsedProductIds = browseHistory.stream()
                .map(UserBrowseHistory::getProductId)
                .collect(Collectors.toList());
                
            List<Product> recommendedProducts = new ArrayList<>();
            
            // Get products from the same categories as browsed items
            if (!browsedProductIds.isEmpty()) {
                List<Product> browsedProducts = listByIds(browsedProductIds);
                List<Long> categoryIds = browsedProducts.stream()
                    .map(Product::getCategoryId)
                    .distinct()
                    .collect(Collectors.toList());
                    
                LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.in(Product::getCategoryId, categoryIds)
                    .eq(Product::getStatus, 1)  // Available products only
                    .gt(Product::getStock, 0)   // In stock products
                    .notIn(!browsedProductIds.isEmpty(), Product::getId, browsedProductIds)  // Exclude already browsed products
                    .orderByDesc(Product::getCreateTime)
                    .last("LIMIT 10");
                    
                List<Product> similarProducts = list(queryWrapper);
                recommendedProducts.addAll(similarProducts);
            }
            
            // Add popular products if we need more recommendations
            if (recommendedProducts.size() < 20) {
                LambdaQueryWrapper<Product> popularQuery = new LambdaQueryWrapper<>();
                popularQuery.eq(Product::getStatus, 1)
                    .gt(Product::getStock, 0)
                    .notIn(!recommendedProducts.isEmpty(), Product::getId, 
                        recommendedProducts.stream().map(Product::getId).collect(Collectors.toList()))
                    .orderByDesc(Product::getSales)
                    .last("LIMIT " + (20 - recommendedProducts.size()));
                    
                List<Product> popularProducts = list(popularQuery);
                recommendedProducts.addAll(popularProducts);
            }
            
            // Shuffle the recommendations for variety
            Collections.shuffle(recommendedProducts);
            
            // Convert to DetailVO
            return recommendedProducts.stream()
                .map(this::convertToDetailVO)
                .collect(Collectors.toList());
                
        } catch (Exception e) {
            log.error("Error getting recommended products", e);
            return Collections.emptyList();
        }
    }

    @Override
    public IPage<Product> getProductsByCategory(Long categoryId, Integer pageNum, Integer pageSize) {
        log.info("=== 开始执行getProductsByCategory ===");
        log.info("输入参数: categoryId={}, pageNum={}, pageSize={}", categoryId, pageNum, pageSize);
        
        // 参数验证
        if (categoryId == null || categoryId <= 0) {
            log.error("分类ID无效: categoryId={}", categoryId);
            throw new BusinessException("无效的分类ID");
        }
        
        if (pageNum == null || pageNum < 1) {
            log.info("页码为空或小于1，使用默认值1");
            pageNum = 1;
        }
        if (pageSize == null || pageSize < 1) {
            log.info("每页大小为空或小于1，使用默认值10");
            pageSize = 10;
        }
        
        try {
            // 验证分类是否存在
            log.debug("开始验证分类是否存在");
            ProductCategory category = categoryService.getById(categoryId);
            if (category == null) {
                log.error("分类不存在: categoryId={}", categoryId);
                throw new BusinessException("分类不存在");
            }
            log.info("分类验证成功: categoryId={}, categoryName={}", category.getId(), category.getName());
            
            // 构建查询条件
            log.debug("开始构建查询条件");
            LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Product::getCategoryId, categoryId)
                   .eq(Product::getStatus, 1)  // 只查询上架商品
                   .eq(Product::getDeleted, 0)  // 未删除的商品
                   .orderByDesc(Product::getCreateTime);
            
            log.debug("查询条件构建完成: {}", wrapper.getSqlSegment());
            
            // 执行分页查询
            log.debug("开始执行分页查询: pageNum={}, pageSize={}", pageNum, pageSize);
            Page<Product> page = new Page<>(pageNum, pageSize);
            IPage<Product> result = this.page(page, wrapper);
            
            if (result == null) {
                log.warn("查询结果为空");
                return null;
            }
            
            log.info("查询完成: 总记录数={}, 当前页={}, 每页大小={}, 总页数={}", 
                result.getTotal(), result.getCurrent(), result.getSize(), result.getPages());
            
            if (result.getRecords() != null && !result.getRecords().isEmpty()) {
                log.debug("查询到的记录数: {}", result.getRecords().size());
                result.getRecords().forEach(product -> 
                    log.debug("商品记录: id={}, name={}, price={}, stock={}", 
                        product.getId(), product.getName(), product.getPrice(), product.getStock())
                );
            } else {
                log.info("没有查询到商品记录");
            }
            
            return result;
        } catch (BusinessException e) {
            log.error("业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("系统异常", e);
            throw new BusinessException("获取分类商品列表失败: " + e.getMessage());
        } finally {
            log.info("=== 结束执行getProductsByCategory ===");
        }
    }

    @Override
    public IPage<Product> getProductsByMerchant(Long merchantId, Integer pageNum, Integer pageSize) {
        return this.page(
            new Page<>(pageNum, pageSize),
            new LambdaQueryWrapper<Product>()
                .eq(Product::getMerchantId, merchantId)
                .orderByDesc(Product::getCreateTime)
        );
    }

    @Override
    public IPage<Product> searchProducts(String keyword, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Product::getName, keyword)
               .or()
               .like(Product::getSubtitle, keyword)
               .eq(Product::getStatus, 1)
               .orderByDesc(Product::getSales);
        return this.page(new Page<>(pageNum, pageSize), wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSales(Long id, Integer quantity) {
        Product product = this.getById(id);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }

        product.setSales(product.getSales() + quantity);
        return this.updateById(product);
    }

    @Override
    public List<ProductDetailVO> getHotProducts(Integer limit) {
        // 获取热销商品列表
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getStatus, 1)  // 上架状态
                .orderByDesc(Product::getSales)  // 按销量排序
                .last("LIMIT " + limit);  // 限制条数
        
        List<Product> products = list(wrapper);
        return convertToDetailVOList(products);
    }

    @Override
    public List<ProductDetailVO> getNewProducts(Integer limit) {
        // 获取新品列表
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getStatus, 1)  // 上架状态
                .orderByDesc(Product::getCreateTime)  // 按创建时间排序
                .last("LIMIT " + limit);  // 限制条数
        
        List<Product> products = list(wrapper);
        return convertToDetailVOList(products);
    }

    /**
     * 转换为商品详情VO列表
     * @param products 商品列表
     * @return 商品详情VO列表
     */
    private List<ProductDetailVO> convertToDetailVOList(List<Product> products) {
        if (products == null || products.isEmpty()) {
            return new ArrayList<>();
        }
        
        return products.stream().map(this::convertToDetailVO).collect(Collectors.toList());
    }

    @Override
    public Page<Product> pageProducts(ProductQueryDTO queryDTO) {
        Page<Product> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();

        // 设置商家ID条件
        wrapper.eq(Product::getMerchantId, queryDTO.getMerchantId());

        // 设置查询条件
        wrapper.like(StringUtils.hasText(queryDTO.getKeyword()), Product::getName, queryDTO.getKeyword())
                .eq(queryDTO.getCategoryId() != null, Product::getCategoryId, queryDTO.getCategoryId())
                .eq(queryDTO.getStatus() != null, Product::getStatus, queryDTO.getStatus())
                .eq(queryDTO.getIsRecommend() != null, Product::getIsRecommend, queryDTO.getIsRecommend())
                .eq(queryDTO.getIsNew() != null, Product::getIsNew, queryDTO.getIsNew())
                .eq(queryDTO.getIsHot() != null, Product::getIsHot, queryDTO.getIsHot())
                .ge(queryDTO.getMinPrice() != null, Product::getPrice, queryDTO.getMinPrice())
                .le(queryDTO.getMaxPrice() != null, Product::getPrice, queryDTO.getMaxPrice());

        // 设置排序
        Integer sortField = queryDTO.getSortField();
        if (sortField != null) {
            boolean isAscending = "asc".equals(queryDTO.getSortOrder());
            if (sortField == 1) {  // price
                wrapper.orderBy(true, isAscending, Product::getPrice);
            } else if (sortField == 2) {  // sales
                wrapper.orderBy(true, isAscending, Product::getSales);
            } else if (sortField == 3) {  // createTime
                wrapper.orderBy(true, isAscending, Product::getCreateTime);
            }
        } else {
            // 默认按创建时间倒序
            wrapper.orderByDesc(Product::getCreateTime);
        }

        return page(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean increaseSales(Long id, Integer quantity) {
        Product product = getById(id);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }
        
        product.setSales(product.getSales() + quantity);
        boolean result = updateById(product);
        if (result) {
            redisUtils.delete(PRODUCT_CACHE_KEY + id);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean increaseViewCount(Long id) {
        Product product = getById(id);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }
        
        product.setViewCount(product.getViewCount() + 1);
        boolean result = updateById(product);
        if (result) {
            redisUtils.delete(PRODUCT_CACHE_KEY + id);
        }
        return result;
    }

    @Override
    public List<String> getSearchSuggestions(String keyword, Integer limit) {
        if (!StringUtils.hasText(keyword)) {
            // 如果关键词为空，返回热门搜索
            return redisUtils.zRevRange(HOT_SEARCH_KEY, 0, limit - 1)
                .stream()
                .collect(Collectors.toList());
        }

        // 1. 先从商品名称中模糊搜索
        LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Product::getName)
                   .like(Product::getName, keyword)
                   .eq(Product::getStatus, 1)  // 只搜索上架商品
                   .orderByDesc(Product::getSales)  // 按销量排序
                   .last("LIMIT " + limit);  // 限制返回数量

        List<String> suggestions = list(queryWrapper)
            .stream()
            .map(Product::getName)
            .collect(Collectors.toList());

        // 2. 如果商品名称搜索结果不足，补充热门搜索
        if (suggestions.size() < limit) {
            int remaining = limit - suggestions.size();
            List<String> hotSearches = redisUtils.zRevRange(HOT_SEARCH_KEY, 0, remaining - 1)
                .stream()
                .filter(s -> s.contains(keyword))
                .collect(Collectors.toList());
            suggestions.addAll(hotSearches);
        }

        return suggestions;
    }

    // 更新热门搜索
    private void updateHotSearch(String keyword) {
        String key = HOT_SEARCH_KEY;
        Double score = redisUtils.zScore(key, keyword);
        if (score == null) {
            score = 0.0;
        }
        redisUtils.zAdd(key, keyword, score + 1);
        
        // 保持热门搜索数量在限制范围内
        Long size = redisUtils.zCard(key);
        if (size > MAX_SUGGESTIONS) {
            redisUtils.zRemRangeByRank(key, 0, size - MAX_SUGGESTIONS - 1);
        }
    }

    @Override
    public void saveSearchHistory(Long userId, String keyword) {
        if (userId == null || !StringUtils.hasText(keyword)) {
            return;
        }
        
        try {
            String key = SEARCH_HISTORY_KEY + userId;
            double score = System.currentTimeMillis();
            
            // 添加新的搜索记录
            redisUtils.zAdd(key, keyword, score);
            
            // 保持历史记录数量在限制范围内
            long size = redisUtils.zCard(key);
            if (size > MAX_SEARCH_HISTORY) {
                redisUtils.zRemRangeByRank(key, 0, size - MAX_SEARCH_HISTORY - 1);
            }
        } catch (Exception e) {
            log.error("Error saving search history for user {}: ", userId, e);
        }
    }

    @Override
    public List<String> getSearchHistory(Long userId, Integer limit) {
        if (userId == null) {
            return Collections.emptyList();
        }
        
        try {
            String key = SEARCH_HISTORY_KEY + userId;
            return new ArrayList<>(redisUtils.zRevRange(key, 0, limit - 1));
        } catch (Exception e) {
            log.error("Error getting search history for user {}: ", userId, e);
            return Collections.emptyList();
        }
    }

    @Override
    public void clearSearchHistory(Long userId) {
        if (userId == null) {
            return;
        }
        
        try {
            String key = SEARCH_HISTORY_KEY + userId;
            redisUtils.delete(key);
        } catch (Exception e) {
            log.error("Error clearing search history for user {}: ", userId, e);
        }
    }

    private ProductDetailVO convertToDetailVO(Product product) {
        if (product == null) {
            return null;
        }

        ProductDetailVO vo = new ProductDetailVO();
        BeanUtils.copyProperties(product, vo);

        // 设置分类信息
        ProductCategory category = categoryService.getById(product.getCategoryId());
        if (category != null) {
            vo.setCategoryName(category.getName());
        }

        // 设置商家信息
        Merchant merchant = baseMapper.selectMerchantById(product.getMerchantId());
        if (merchant != null) {
            vo.setMerchantName(merchant.getShopName());
        }

        // 设置SKU信息
        List<ProductSku> skuList = skuService.getByProductId(product.getId());
        vo.setSkuList(skuList.stream()
                .map(sku -> {
                    ProductSkuDTO skuDTO = new ProductSkuDTO();
                    BeanUtils.copyProperties(sku, skuDTO);
                    return skuDTO;
                })
                .collect(Collectors.toList()));

        return vo;
    }

    @Override
    public List<Product> getNewProducts(Long categoryId, Integer limit) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(categoryId != null, Product::getCategoryId, categoryId)
               .eq(Product::getStatus, 1)
               .orderByDesc(Product::getCreateTime)
               .last("LIMIT " + limit);
        return list(wrapper);
    }

    @Override
    public void incrementViewCount(Long productId) {
        Product product = getById(productId);
        if (product != null) {
            product.setViewCount(product.getViewCount() + 1);
            updateById(product);
            // 更新缓存
            String key = PRODUCT_CACHE_KEY + productId;
            redisUtils.delete(key);
        }
    }

    @Override
    public List<Product> getHotProducts(Long categoryId, Integer limit) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(categoryId != null, Product::getCategoryId, categoryId)
               .eq(Product::getStatus, 1)
               .orderByDesc(Product::getSales)
               .last("LIMIT " + limit);
        return list(wrapper);
    }

    @Override
    public IPage<Product> getShopProducts(Long shopId, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getMerchantId, shopId)
               .eq(Product::getStatus, 1)
               .orderByDesc(Product::getCreateTime);
        return page(new Page<>(pageNum, pageSize), wrapper);
    }

    @Override
    public IPage<Product> searchProducts(ProductSearchDTO searchDTO) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        // 关键词搜索
        if (StringUtils.hasText(searchDTO.getKeyword())) {
            wrapper.and(w -> w.like(Product::getName, searchDTO.getKeyword())
                    .or()
                    .like(Product::getSubtitle, searchDTO.getKeyword()));
        }
        // 分类过滤
        if (searchDTO.getCategoryId() != null) {
            wrapper.eq(Product::getCategoryId, searchDTO.getCategoryId());
        }
        // 价格区间
        if (searchDTO.getMinPrice() != null) {
            wrapper.ge(Product::getPrice, searchDTO.getMinPrice());
        }
        if (searchDTO.getMaxPrice() != null) {
            wrapper.le(Product::getPrice, searchDTO.getMaxPrice());
        }
        // 销量范围
        if (searchDTO.getMinSales() != null) {
            wrapper.ge(Product::getSales, searchDTO.getMinSales());
        }
        if (searchDTO.getMaxSales() != null) {
            wrapper.le(Product::getSales, searchDTO.getMaxSales());
        }
        // 商家过滤
        if (searchDTO.getMerchantId() != null) {
            wrapper.eq(Product::getMerchantId, searchDTO.getMerchantId());
        }
        // 库存过滤
        if (searchDTO.getHasStock() != null && searchDTO.getHasStock() == 1) {
            wrapper.gt(Product::getStock, 0);
        }
        // 排序
        if (searchDTO.getSortField() != null) {
            switch (searchDTO.getSortField()) {
                case 1: // 综合排序
                    wrapper.orderByDesc(Product::getSales, Product::getCreateTime);
                    break;
                case 2: // 销量
                    wrapper.orderByDesc(Product::getSales);
                    break;
                case 3: // 价格升序
                    wrapper.orderByAsc(Product::getPrice);
                    break;
                case 4: // 价格降序
                    wrapper.orderByDesc(Product::getPrice);
                    break;
                case 5: // 新品
                    wrapper.orderByDesc(Product::getCreateTime);
                    break;
                default:
                    wrapper.orderByDesc(Product::getCreateTime);
            }
        }
        return page(new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize()), wrapper);
    }

    @Override
    public List<Product> getRelatedProducts(Long productId, Integer limit) {
        Product product = getById(productId);
        if (product == null) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Product::getCategoryId, product.getCategoryId())
               .eq(Product::getStatus, 1)
               .ne(Product::getId, productId)
               .orderByDesc(Product::getSales)
               .last("LIMIT " + limit);
        return list(wrapper);
    }

    @Override
    public IPage<Product> searchMerchantProducts(ProductSearchDTO searchDTO, Integer status) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(searchDTO.getKeyword())) {
            wrapper.and(w -> w.like(Product::getName, searchDTO.getKeyword())
                    .or()
                    .like(Product::getSubtitle, searchDTO.getKeyword()));
        }
        
        // 分类过滤
        if (searchDTO.getCategoryId() != null) {
            wrapper.eq(Product::getCategoryId, searchDTO.getCategoryId());
        }
        
        // 商家ID过滤（必须是当前商家）
        wrapper.eq(Product::getMerchantId, searchDTO.getMerchantId());
        
        // 状态过滤
        if (status != null) {
            wrapper.eq(Product::getStatus, status);
        }
        
        // 只查询未删除商品
        wrapper.eq(Product::getDeleted, 0);
        
        // 排序
        wrapper.orderByDesc(Product::getCreateTime);
        
        // 执行分页查询
        Page<Product> page = new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize());
        return page(page, wrapper);
    }

    @Override
    public IPage<Product> adminSearchProducts(ProductSearchDTO searchDTO, Integer auditStatus) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(searchDTO.getKeyword())) {
            wrapper.and(w -> w.like(Product::getName, searchDTO.getKeyword())
                    .or()
                    .like(Product::getSubtitle, searchDTO.getKeyword()));
        }
        
        // 分类过滤
        if (searchDTO.getCategoryId() != null) {
            wrapper.eq(Product::getCategoryId, searchDTO.getCategoryId());
        }
        
        // 商家ID过滤
        if (searchDTO.getMerchantId() != null) {
            wrapper.eq(Product::getMerchantId, searchDTO.getMerchantId());
        }
        
        // 审核状态过滤
        if (auditStatus != null) {
            wrapper.eq(Product::getAuditStatus, auditStatus);
        }
        
        // 价格区间过滤
        if (searchDTO.getMinPrice() != null) {
            wrapper.ge(Product::getPrice, searchDTO.getMinPrice());
        }
        if (searchDTO.getMaxPrice() != null) {
            wrapper.le(Product::getPrice, searchDTO.getMaxPrice());
        }
        
        // 销量范围过滤
        if (searchDTO.getMinSales() != null) {
            wrapper.ge(Product::getSales, searchDTO.getMinSales());
        }
        if (searchDTO.getMaxSales() != null) {
            wrapper.le(Product::getSales, searchDTO.getMaxSales());
        }
        
        // 库存过滤
        if (searchDTO.getHasStock() != null && searchDTO.getHasStock() == 1) {
            wrapper.gt(Product::getStock, 0);
        }
        
        // 排序
        if (searchDTO.getSortField() != null) {
            switch (searchDTO.getSortField()) {
                case 1: // 综合排序
                    wrapper.orderByDesc(Product::getSales)
                           .orderByDesc(Product::getCreateTime);
                    break;
                case 2: // 销量
                    wrapper.orderByDesc(Product::getSales);
                    break;
                case 3: // 价格升序
                    wrapper.orderByAsc(Product::getPrice);
                    break;
                case 4: // 价格降序
                    wrapper.orderByDesc(Product::getPrice);
                    break;
                case 5: // 最新
                    wrapper.orderByDesc(Product::getCreateTime);
                    break;
                default:
                    wrapper.orderByDesc(Product::getCreateTime);
            }
        } else {
            wrapper.orderByDesc(Product::getCreateTime);
        }
        
        // 执行分页查询
        Page<Product> page = new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize());
        return page(page, wrapper);
    }

    @Override
    public IPage<Product> getAuditPendingProducts(Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        
        // 查询待审核商品
        wrapper.eq(Product::getAuditStatus, 0)  // 0-待审核
               .eq(Product::getDeleted, 0)      // 未删除
               .orderByAsc(Product::getCreateTime);  // 按创建时间升序，先来后到
        
        // 执行分页查询
        Page<Product> page = new Page<>(pageNum, pageSize);
        return page(page, wrapper);
    }

    @Override
    @Transactional
    public boolean addReview(Long userId, Long productId, String content, Integer rating) {
        // 验证用户
        User user = userService.getById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }

        // 验证商品
        Product product = this.getById(productId);
        if (product == null) {
            throw new BusinessException("商品不存在");
        }

        // 验证评分
        if (rating < 1 || rating > 5) {
            throw new BusinessException("评分必须在1-5之间");
        }

        // 创建评论
        ProductReview review = new ProductReview();
        review.setUserId(userId);
        review.setProductId(productId);
        review.setContent(content);
        review.setRating(rating);
        review.setCreateTime(new Date());
        review.setStatus(1); // 1: 正常

        // 保存评论
        boolean success = reviewMapper.insert(review) > 0;
        if (success) {
            // 更新商品评分
            updateProductRating(productId);
        }
        return success;
    }

    @Override
    @Transactional
    public boolean replyReview(Long reviewId, String replyContent) {
        ProductReview review = reviewMapper.selectById(reviewId);
        if (review == null) {
            throw new BusinessException("评论不存在");
        }

        review.setReplyContent(replyContent);
        review.setReplyTime(new Date());
        return reviewMapper.updateById(review) > 0;
    }

    @Override
    @Transactional
    public boolean deleteReview(Long reviewId) {
        ProductReview review = reviewMapper.selectById(reviewId);
        if (review == null) {
            throw new BusinessException("评论不存在");
        }

        review.setStatus(0); // 0: 已删除
        boolean success = reviewMapper.updateById(review) > 0;
        if (success) {
            // 更新商品评分
            updateProductRating(review.getProductId());
        }
        return success;
    }

    @Override
    public List<ProductReviewVO> getProductReviews(Long productId, Integer page, Integer size) {
        Page<ProductReview> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getProductId, productId)
                .eq(ProductReview::getStatus, 1)
                .orderByDesc(ProductReview::getCreateTime);

        IPage<ProductReview> reviewPage = reviewMapper.selectPage(pageParam, wrapper);
        return reviewPage.getRecords().stream()
                .map(this::convertToReviewVO)
                .collect(Collectors.toList());
    }

    @Override
    public Map<String, Object> getReviewStats(Long productId) {
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getProductId, productId)
                .eq(ProductReview::getStatus, 1);

        List<ProductReview> reviews = reviewMapper.selectList(wrapper);
        
        Map<String, Object> stats = new HashMap<>();
        stats.put("total", reviews.size());
        
        // 计算各评分数量
        Map<Integer, Long> ratingCounts = reviews.stream()
                .collect(Collectors.groupingBy(ProductReview::getRating, Collectors.counting()));
        stats.put("ratingCounts", ratingCounts);
        
        // 计算平均评分
        double avgRating = reviews.stream()
                .mapToInt(ProductReview::getRating)
                .average()
                .orElse(0.0);
        stats.put("averageRating", avgRating);
        
        return stats;
    }

    @Override
    public Integer getReviewCount(Long productId) {
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getProductId, productId)
                .eq(ProductReview::getStatus, 1);
        return reviewMapper.selectCount(wrapper);
    }

    private void updateProductRating(Long productId) {
        Map<String, Object> stats = getReviewStats(productId);
        double avgRating = (double) stats.get("averageRating");
        
        Product product = this.getById(productId);
        if (product != null) {
            product.setRating(avgRating);
            this.updateById(product);
        }
    }

    private ProductReviewVO convertToReviewVO(ProductReview review) {
        ProductReviewVO vo = new ProductReviewVO();
        BeanUtils.copyProperties(review, vo);
        
        // 获取用户信息
        User user = userService.getById(review.getUserId());
        if (user != null) {
            vo.setUsername(user.getUsername());
            vo.setUserAvatar(user.getAvatar());
        }
        
        return vo;
    }

    @Override
    @Transactional
    public boolean likeReview(Long userId, Long reviewId) {
        ProductReview review = reviewMapper.selectById(reviewId);
        if (review == null) {
            throw new BusinessException("评论不存在");
        }
        review.setLikeCount(review.getLikeCount() + 1);
        return reviewMapper.updateById(review) > 0;
    }

    @Override
    @Transactional
    public boolean unlikeReview(Long userId, Long reviewId) {
        ProductReview review = reviewMapper.selectById(reviewId);
        if (review == null) {
            throw new BusinessException("评论不存在");
        }
        if (review.getLikeCount() > 0) {
            review.setLikeCount(review.getLikeCount() - 1);
            return reviewMapper.updateById(review) > 0;
        }
        return true;
    }

    @Override
    public boolean isFavorite(Long userId, Long productId) {
        LambdaQueryWrapper<ProductFavorite> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductFavorite::getUserId, userId)
                .eq(ProductFavorite::getProductId, productId);
        return favoriteMapper.selectCount(wrapper) > 0;
    }

    @Override
    public List<ProductVO> getColdStartRecommendations(Long userId, Integer limit) {
        // 对于新用户，返回评分最高的商品
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Product::getRating)
                .last("LIMIT " + limit);
        return this.list(wrapper).stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean cancelFavorite(Long userId, Long productId) {
        LambdaQueryWrapper<ProductFavorite> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductFavorite::getUserId, userId)
                .eq(ProductFavorite::getProductId, productId);
        return favoriteMapper.delete(wrapper) > 0;
    }

    @Override
    public Double getAverageRating(Long productId) {
        Map<String, Object> stats = getReviewStats(productId);
        return (Double) stats.get("averageRating");
    }

    @Override
    public List<ProductVO> getBrowseHistoryRecommendations(Long userId, Integer limit) {
        // 基于用户浏览历史推荐相似商品
        List<Long> productIds = browseHistoryMapper.selectProductIdsByUserId(userId, limit);
        if (productIds.isEmpty()) {
            return getColdStartRecommendations(userId, limit);
        }
        
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Product::getId, productIds)
                .orderByDesc(Product::getRating)
                .last("LIMIT " + limit);
        return this.list(wrapper).stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<ProductReviewVO> getUserReviews(Long userId, Integer page, Integer size) {
        Page<ProductReview> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<ProductReview> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductReview::getUserId, userId)
                .eq(ProductReview::getStatus, 1)
                .orderByDesc(ProductReview::getCreateTime);

        IPage<ProductReview> reviewPage = reviewMapper.selectPage(pageParam, wrapper);
        return reviewPage.getRecords().stream()
                .map(this::convertToReviewVO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean deleteReview(Long userId, Long reviewId) {
        ProductReview review = reviewMapper.selectById(reviewId);
        if (review == null || !review.getUserId().equals(userId)) {
            throw new BusinessException("评论不存在或无权限删除");
        }
        review.setStatus(0); // 0: 已删除
        boolean success = reviewMapper.updateById(review) > 0;
        if (success) {
            updateProductRating(review.getProductId());
        }
        return success;
    }

    @Override
    public List<ProductVO> getPersonalizedRecommendations(Long userId, Integer limit) {
        // 基于用户历史行为（浏览、收藏、评论）进行个性化推荐
        List<Long> favoriteProductIds = favoriteMapper.selectProductIdsByUserId(userId);
        List<Long> reviewProductIds = reviewMapper.selectProductIdsByUserId(userId);
        List<Long> browseProductIds = browseHistoryMapper.selectProductIdsByUserId(userId, 10);

        // 合并所有商品ID并去重
        Set<Long> allProductIds = new HashSet<>();
        allProductIds.addAll(favoriteProductIds);
        allProductIds.addAll(reviewProductIds);
        allProductIds.addAll(browseProductIds);

        if (allProductIds.isEmpty()) {
            return getColdStartRecommendations(userId, limit);
        }

        // 查询相似商品
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Product::getId, allProductIds)
                .orderByDesc(Product::getRating)
                .last("LIMIT " + limit);
        return this.list(wrapper).stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean addFavorite(Long userId, Long productId) {
        // 检查是否已收藏
        if (isFavorite(userId, productId)) {
            return true;
        }

        ProductFavorite favorite = new ProductFavorite();
        favorite.setUserId(userId);
        favorite.setProductId(productId);
        favorite.setCreateTime(new Date());
        return favoriteMapper.insert(favorite) > 0;
    }

    @Override
    public List<ProductVO> getFavoriteRecommendations(Long userId, Integer limit) {
        // 获取用户收藏的商品
        List<Long> favoriteProductIds = favoriteMapper.selectProductIdsByUserId(userId);
        if (favoriteProductIds.isEmpty()) {
            return getColdStartRecommendations(userId, limit);
        }

        // 基于收藏的商品推荐相似商品
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Product::getId, favoriteProductIds)
                .orderByDesc(Product::getRating)
                .last("LIMIT " + limit);
        return this.list(wrapper).stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<ProductVO> getDiversityRecommendations(Long userId, Integer limit) {
        // 获取用户历史行为的商品ID
        Set<Long> userProductIds = new HashSet<>();
        userProductIds.addAll(favoriteMapper.selectProductIdsByUserId(userId));
        userProductIds.addAll(reviewMapper.selectProductIdsByUserId(userId));
        userProductIds.addAll(browseHistoryMapper.selectProductIdsByUserId(userId, 10));

        if (userProductIds.isEmpty()) {
            return getColdStartRecommendations(userId, limit);
        }

        // 查询与用户历史行为不同的商品
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.notIn(Product::getId, userProductIds)
                .orderByDesc(Product::getRating)
                .last("LIMIT " + limit);
        return this.list(wrapper).stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public List<ProductVO> getUserFavorites(Long userId, Integer page, Integer size) {
        Page<ProductFavorite> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<ProductFavorite> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductFavorite::getUserId, userId)
                .orderByDesc(ProductFavorite::getCreateTime);

        IPage<ProductFavorite> favoritePage = favoriteMapper.selectPage(pageParam, wrapper);
        List<Long> productIds = favoritePage.getRecords().stream()
                .map(ProductFavorite::getProductId)
                .collect(Collectors.toList());

        if (productIds.isEmpty()) {
            return new ArrayList<>();
        }

        LambdaQueryWrapper<Product> productWrapper = new LambdaQueryWrapper<>();
        productWrapper.in(Product::getId, productIds);
        return this.list(productWrapper).stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public Integer getFavoriteCount(Long productId) {
        LambdaQueryWrapper<ProductFavorite> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProductFavorite::getProductId, productId);
        return favoriteMapper.selectCount(wrapper);
    }

    @Override
    public List<ProductVO> getSearchHistoryRecommendations(Long userId, Integer limit) {
        // 获取用户搜索历史
        List<String> searchKeywords = searchHistoryMapper.selectKeywordsByUserId(userId, 10);
        if (searchKeywords.isEmpty()) {
            return getColdStartRecommendations(userId, limit);
        }

        // 基于搜索关键词推荐商品
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(w -> {
            for (String keyword : searchKeywords) {
                w.or().like(Product::getName, keyword)
                  .or().like(Product::getDescription, keyword);
            }
        });
        wrapper.orderByDesc(Product::getRating)
                .last("LIMIT " + limit);
        return this.list(wrapper).stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }
} 